#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>

//对于生产者：首先申请信号量；生产；更新下表；维持环状特性（取模运算）
//如果要支持多生产多消费，在申请信号量之前加锁即可
//我们使用一组信号量，一组数组下标：
//信号量表示资源是否就绪，取得信号量这个入场券就可以
//放资源或者去资源，2而数组下标存在的意义是让我们的资源得到分配

//如果资源是整体的，那就使用互斥锁；如果是分块使用的，那就使用信号量
//通过二元信号量就可以在使用整体资源时互相通知对方自己是否完成工作

//信号量的本质就是临界区资源数量，通过信号量自己就能判断资源是否就绪
//在设计好这个信号量的结构体之后，我们就可以在实现一个runqueue来完整实现
//基于环形队列的生产者、消费者模型，用信号量来作为将一块临界资源分块使用的
//入场券，只要有线程进入这个临界区域，我们的信号量就进行对应的++/--操作
//这一步满足了不会生产者套消费者一圈以上，而我们的两个数组下标，就是给
//已经获取到信号量的线程关于在哪里拿或放数据的信息，这样我们就实现了生产者
//和消费者之间的同步与互斥；而至于生产者和生产者、消费者和消费者之间互斥关系
//我们选择通过互斥锁来实现，这样321就都满足了（我们选择先获取信号量再去获取互斥锁）

namespace sem_module
{
    class semaphore
    {
        public:
        semaphore(unsigned int sem_value)
        {
            //第二个参数是信号量的初始值
            sem_init(&_sem, 0, sem_value);
        }

        void P()
        {
            //将信号量的资源-1
            sem_wait(&_sem);
        }

        void V()
        {
            //将信号量的值+1，表示资源使用完了可以归还资源
            sem_post(&_sem);//P、V操作都是原子的
        }

        ~semaphore()
        {
            sem_destroy(&_sem);
        }
        private:
        sem_t _sem;
    };
}